package config

import (
	"sieve_engine/lib/util/file"
	"strconv"
	"strings"
)

func parseIni(path string) ParsedData {
	m := ParsedData{}
	lines, err := file.ReadLines(path)
	if err != nil {
		return m
	}
	prefixStack := []string{}
	prefixCnt := map[string]int{}
	lastKey := ""
	for _, line := range lines {
		if line == "" {
			continue
		}
		if line[0] == '#' {
			continue
		}
		if line[0] == '[' {
			prefix, level, hasCnt := parsePrefix(line)
			if level == 0 {
				prefixStack = []string{}
			}
			if level > len(prefixStack) {
				panic("prefix level error")
			}
			if hasCnt {
				stack := prefixStack[:level]
				if prefix == "" {
					stack = append(stack, "$")
				} else {
					stack = append(stack, prefix+".$")
				}
				p := strings.Join(stack, ".") // xx.yy.$
				// fmt.Println("p: " + p)
				cnt := strconv.Itoa(prefixCnt[p])
				if prefix == "" {
					prefix = cnt
				} else {
					prefix += "." + cnt
				}
				prefixCnt[p]++
			}
			if prefix != "" {
				prefixStack = append(prefixStack[:level], prefix)
			}
			lastKey = ""
			continue
		}
		ss := strings.SplitN(line, "=", 2)
		if len(ss) != 2 { // value为空时默认空字符串
			// panic("kv format error. = is missing")
			ss = append(ss, "")
		}
		k := strings.TrimSpace(ss[0])
		if k == "" && lastKey != "" { // key为空的时候默认等于前一个key
			k = lastKey
		} else {
			checkFields(k)
			if len(prefixStack) > 0 {
				k = strings.Join(prefixStack, ".") + "." + k
			}
			lastKey = k
		}
		v := strings.TrimSpace(ss[1])
		m.Add(k, parseString(v))
		// fmt.Println(k)
	}
	for k, v := range prefixCnt {
		m.Add(k, strconv.Itoa(v))
	}
	return m
}

func parsePrefix(line string) (prefix string, level int, hasCnt bool) {
	if line[0] != '[' || line[len(line)-1] != ']' {
		panic("prefix format error")
	}
	prefix = line[1 : len(line)-1]
	if prefix == "" {
		return
	}
	for _, c := range prefix {
		if c != '.' {
			break
		}
		level++
	}
	prefix = prefix[level:]
	if prefix == "" {
		panic("prefix field not found")
	}
	if ss := strings.Split(prefix, "."); ss[len(ss)-1] == "$" {
		hasCnt = true
		prefix = strings.Join(ss[:len(ss)-1], ".")
	}
	// fmt.Println("check " + prefix)
	if prefix != "" {
		checkFields(prefix)
	}
	return
}
